package no.uib.mitraq.gui;

import java.awt.Color;
import no.uib.mitraq.renderers.AlignedListCellRenderer;
import no.uib.mitraq.util.SsvFileFilter;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

/**
 * A dialog for displaying and setting the experimental design for an MiTRAQ 
 * experiment.
 *
 * @author Harald Barsnes
 */
public class ExperimentalDesign extends javax.swing.JDialog implements ProgressDialogParent {

    /**
     * A reference to the MiTRAQ main frame.
     */
    private MiTRAQ mitraq;
    /**
     * The labels used in 4-plex iTRAQ.
     */
    private Vector<String> iTraq4PlexLabels = new Vector<String>();
    /**
     * The labels used in 8-plex iTRAQ.
     */
    private Vector<String> iTraq8PlexLabels = new Vector<String>();
    /**
     * If set to true the opening of the file is stopped.
     */
    private boolean cancelProgress = false;
    /**
     * The progress dialog.
     */
    private ProgressDialog progressDialog;

    /**
     * Creates a new ExperimentalDesign dialog.
     *
     * @param mitraq the MiTRAQ parent frame
     * @param modal if the dialog should be modal or not
     * @param currentRatioFile the ratio file to display/set up the experimental design for
     */
    public ExperimentalDesign(MiTRAQ mitraq, boolean modal, String currentRatioFile) {
        super(mitraq, modal);

        this.mitraq = mitraq;

        initComponents();
        
        expDesignJScrollPane.getViewport().setOpaque(false);

        ratioFileJTextField.setText(currentRatioFile);

        iTraqTypeJComboBox.setRenderer(new AlignedListCellRenderer(SwingConstants.CENTER));
        iTraqReferenceJComboBox.setRenderer(new AlignedListCellRenderer(SwingConstants.CENTER));
        ((DefaultEditor) numberOfExperimentsJSpinner.getEditor()).getTextField().setHorizontalAlignment(JTextField.CENTER);
        ((DefaultEditor) numberOfGroupsJSpinner.getEditor()).getTextField().setHorizontalAlignment(JTextField.CENTER);

        experimentalDesignJTable.getTableHeader().setReorderingAllowed(false);

        iTraq4PlexLabels.add("114");
        iTraq4PlexLabels.add("115");
        iTraq4PlexLabels.add("116");
        iTraq4PlexLabels.add("117");

        iTraq8PlexLabels.add("113");
        iTraq8PlexLabels.add("114");
        iTraq8PlexLabels.add("115");
        iTraq8PlexLabels.add("116");
        iTraq8PlexLabels.add("117");
        iTraq8PlexLabels.add("118");
        iTraq8PlexLabels.add("119");
        iTraq8PlexLabels.add("121");

        updateExperiementalDesign();
        numberOfGroupsJSpinnerStateChanged(null);

        if (currentRatioFile != null) {
            if (new File(mitraq.getJarFilePath() + "/resources/conf/" + new File(ratioFileJTextField.getText()).getName() + ".exp").exists()) {
                readExperimentalDesignSettings(mitraq.getJarFilePath() + "/resources/conf/" + new File(ratioFileJTextField.getText()).getName() + ".exp");
            }
        }

        this.setLocationRelativeTo(this);
        this.setVisible(true);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        backgroundPanel = new javax.swing.JPanel();
        ratioFilePanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        ratioFileJTextField = new javax.swing.JTextField();
        findInputFileJButton = new javax.swing.JButton();
        experimentalSetupPanel = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        groupOneLabelJTextField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        groupTwoLabelJTextField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        numberOfExperimentsJSpinner = new javax.swing.JSpinner();
        jLabel3 = new javax.swing.JLabel();
        iTraqTypeJComboBox = new javax.swing.JComboBox();
        iTraqReferenceJComboBox = new javax.swing.JComboBox();
        jLabel4 = new javax.swing.JLabel();
        expDesignJScrollPane = new javax.swing.JScrollPane();
        experimentalDesignJTable = new javax.swing.JTable();
        numberOfGroupsJSpinner = new javax.swing.JSpinner();
        groupAColorJPanel = new javax.swing.JPanel();
        groupBColorJPanel = new javax.swing.JPanel();
        loadJButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("MiTRAQ - Experimental Design");
        setResizable(false);

        backgroundPanel.setBackground(new java.awt.Color(230, 230, 230));

        ratioFilePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Spectrum Mill Input"));
        ratioFilePanel.setOpaque(false);

        jLabel1.setText("iTRAQ Ratio File:");

        findInputFileJButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/Directory.gif"))); // NOI18N
        findInputFileJButton.setToolTipText("Select Input File");
        findInputFileJButton.setBorderPainted(false);
        findInputFileJButton.setContentAreaFilled(false);
        findInputFileJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                findInputFileJButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout ratioFilePanelLayout = new javax.swing.GroupLayout(ratioFilePanel);
        ratioFilePanel.setLayout(ratioFilePanelLayout);
        ratioFilePanelLayout.setHorizontalGroup(
            ratioFilePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ratioFilePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(ratioFileJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 730, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(findInputFileJButton, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        ratioFilePanelLayout.setVerticalGroup(
            ratioFilePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ratioFilePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ratioFilePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, ratioFilePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(ratioFileJTextField)
                        .addComponent(jLabel1))
                    .addComponent(findInputFileJButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addContainerGap())
        );

        experimentalSetupPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Experimental Setup"));
        experimentalSetupPanel.setOpaque(false);

        jLabel5.setText("Number of Groups:");

        jLabel6.setText("Group 1:");

        groupOneLabelJTextField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        groupOneLabelJTextField.setText("A");
        groupOneLabelJTextField.setToolTipText("Label for Group A");
        groupOneLabelJTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                groupOneLabelJTextFieldKeyReleased(evt);
            }
        });

        jLabel7.setText("Group 2:");

        groupTwoLabelJTextField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        groupTwoLabelJTextField.setText("B");
        groupTwoLabelJTextField.setToolTipText("Label for Group B");
        groupTwoLabelJTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                groupTwoLabelJTextFieldKeyReleased(evt);
            }
        });

        jLabel2.setText("Number of Experiments:");

        numberOfExperimentsJSpinner.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(4), Integer.valueOf(2), null, Integer.valueOf(1)));
        numberOfExperimentsJSpinner.setToolTipText("Number of iTRAQ Experiments");
        numberOfExperimentsJSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                numberOfExperimentsJSpinnerStateChanged(evt);
            }
        });

        jLabel3.setText("iTRAQ Type:");

        iTraqTypeJComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "4-plex", "8-plex" }));
        iTraqTypeJComboBox.setToolTipText("iTRAQ Type");
        iTraqTypeJComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                iTraqTypeJComboBoxActionPerformed(evt);
            }
        });

        iTraqReferenceJComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "114", "115", "116", "117" }));
        iTraqReferenceJComboBox.setToolTipText("iTRAQ Reference");
        iTraqReferenceJComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                iTraqReferenceJComboBoxActionPerformed(evt);
            }
        });

        jLabel4.setText("iTRAQ Reference:");

        experimentalDesignJTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null}
            },
            new String [] {
                "Exp.", "114", "115", "116", "117"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        expDesignJScrollPane.setViewportView(experimentalDesignJTable);

        numberOfGroupsJSpinner.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(2), Integer.valueOf(1), null, Integer.valueOf(1)));
        numberOfGroupsJSpinner.setToolTipText("Number of Groups to Compare");
        numberOfGroupsJSpinner.setEnabled(false);
        numberOfGroupsJSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                numberOfGroupsJSpinnerStateChanged(evt);
            }
        });

        groupAColorJPanel.setBackground(new java.awt.Color(255, 51, 51));
        groupAColorJPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        groupAColorJPanel.setToolTipText("The color used for Group 1");
        groupAColorJPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                groupAColorJPanelMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout groupAColorJPanelLayout = new javax.swing.GroupLayout(groupAColorJPanel);
        groupAColorJPanel.setLayout(groupAColorJPanelLayout);
        groupAColorJPanelLayout.setHorizontalGroup(
            groupAColorJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 21, Short.MAX_VALUE)
        );
        groupAColorJPanelLayout.setVerticalGroup(
            groupAColorJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        groupBColorJPanel.setBackground(new java.awt.Color(51, 51, 255));
        groupBColorJPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        groupBColorJPanel.setToolTipText("The color used for Group 2");
        groupBColorJPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                groupBColorJPanelMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout groupBColorJPanelLayout = new javax.swing.GroupLayout(groupBColorJPanel);
        groupBColorJPanel.setLayout(groupBColorJPanelLayout);
        groupBColorJPanelLayout.setHorizontalGroup(
            groupBColorJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 21, Short.MAX_VALUE)
        );
        groupBColorJPanelLayout.setVerticalGroup(
            groupBColorJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout experimentalSetupPanelLayout = new javax.swing.GroupLayout(experimentalSetupPanel);
        experimentalSetupPanel.setLayout(experimentalSetupPanelLayout);
        experimentalSetupPanelLayout.setHorizontalGroup(
            experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, experimentalSetupPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(experimentalSetupPanelLayout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addGap(216, 216, 216))
                    .addGroup(experimentalSetupPanelLayout.createSequentialGroup()
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel5)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4)
                            .addGroup(experimentalSetupPanelLayout.createSequentialGroup()
                                .addGap(10, 10, 10)
                                .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel6)
                                    .addComponent(jLabel7))))
                        .addGap(55, 55, 55)
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(iTraqTypeJComboBox, 0, 206, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, experimentalSetupPanelLayout.createSequentialGroup()
                                .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(groupTwoLabelJTextField)
                                    .addComponent(groupOneLabelJTextField))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(groupBColorJPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(groupAColorJPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addComponent(numberOfGroupsJSpinner, javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(numberOfExperimentsJSpinner)
                            .addComponent(iTraqReferenceJComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addGap(18, 18, 18)
                .addComponent(expDesignJScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 539, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        experimentalSetupPanelLayout.setVerticalGroup(
            experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, experimentalSetupPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(expDesignJScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addGroup(experimentalSetupPanelLayout.createSequentialGroup()
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(numberOfExperimentsJSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel5)
                            .addComponent(numberOfGroupsJSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(groupAColorJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(groupOneLabelJTextField)
                                .addComponent(jLabel6)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(groupBColorJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(groupTwoLabelJTextField)
                                .addComponent(jLabel7)))
                        .addGap(18, 18, 18)
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(iTraqTypeJComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(experimentalSetupPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(iTraqReferenceJComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel4))))
                .addContainerGap())
        );

        experimentalSetupPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {groupAColorJPanel, groupBColorJPanel, groupOneLabelJTextField, groupTwoLabelJTextField});

        loadJButton.setText("Load iTRAQ Data");
        loadJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadJButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout backgroundPanelLayout = new javax.swing.GroupLayout(backgroundPanel);
        backgroundPanel.setLayout(backgroundPanelLayout);
        backgroundPanelLayout.setHorizontalGroup(
            backgroundPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(backgroundPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(backgroundPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(experimentalSetupPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(ratioFilePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(loadJButton, javax.swing.GroupLayout.Alignment.TRAILING))
                .addContainerGap())
        );
        backgroundPanelLayout.setVerticalGroup(
            backgroundPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(backgroundPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(ratioFilePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(experimentalSetupPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(loadJButton)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(backgroundPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(backgroundPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Opens a file browser where the user can select the file to analyse.
     *
     * @param evt
     */
    private void findInputFileJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findInputFileJButtonActionPerformed

        this.setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));

        JFileChooser chooser = new JFileChooser(ratioFileJTextField.getText());
        chooser.setDialogTitle("Select the Input File");
        chooser.setFileFilter(new SsvFileFilter());

        int returnVal = chooser.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            String path = (chooser.getSelectedFile().getAbsoluteFile().getPath());
            ratioFileJTextField.setText(path);

            if (new File(mitraq.getJarFilePath() + "/resources/conf/" + new File(ratioFileJTextField.getText()).getName() + ".exp").exists()) {
                readExperimentalDesignSettings(mitraq.getJarFilePath() + "/resources/conf/" + new File(ratioFileJTextField.getText()).getName() + ".exp");
            }
        }

        this.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
}//GEN-LAST:event_findInputFileJButtonActionPerformed

    /**
     * Updates the list of group lables to choose from.
     *
     * @param evt
     */
    private void groupOneLabelJTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_groupOneLabelJTextFieldKeyReleased
        numberOfGroupsJSpinnerStateChanged(null);
}//GEN-LAST:event_groupOneLabelJTextFieldKeyReleased

    /**
     * Updates the list of group lables to choose from.
     *
     * @param evt
     */
    private void groupTwoLabelJTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_groupTwoLabelJTextFieldKeyReleased
        numberOfGroupsJSpinnerStateChanged(null);
}//GEN-LAST:event_groupTwoLabelJTextFieldKeyReleased

    /**
     * Updates the experimental design table.
     *
     * @param evt
     */
    private void numberOfExperimentsJSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_numberOfExperimentsJSpinnerStateChanged
        updateExperiementalDesign();
}//GEN-LAST:event_numberOfExperimentsJSpinnerStateChanged

    /**
     * Updates the experimental design table according to the iTRAQ type selected.
     *
     * @param evt
     */
    private void iTraqTypeJComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_iTraqTypeJComboBoxActionPerformed

        String currentITraqType = iTraqTypeJComboBox.getSelectedItem().toString();
        String currentReference = iTraqReferenceJComboBox.getSelectedItem().toString();

        if (currentITraqType.equalsIgnoreCase("4-plex")) {
            iTraqReferenceJComboBox.setModel(new DefaultComboBoxModel(iTraq4PlexLabels));
            iTraqReferenceJComboBox.setSelectedItem(currentReference);
        } else {
            iTraqReferenceJComboBox.setModel(new DefaultComboBoxModel(iTraq8PlexLabels));
            iTraqReferenceJComboBox.setSelectedItem(currentReference);
        }

        updateExperiementalDesign();
}//GEN-LAST:event_iTraqTypeJComboBoxActionPerformed

    /**
     * Updates the experimental design table.
     *
     * @param evt
     */
    private void iTraqReferenceJComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_iTraqReferenceJComboBoxActionPerformed
        updateExperiementalDesign();
}//GEN-LAST:event_iTraqReferenceJComboBoxActionPerformed

    /**
     * Tries to load the iTRAQ data file using the current experimental setup.
     *
     * @param evt
     */
    private void loadJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadJButtonActionPerformed

        this.setVisible(false);

        // store the group colors
        mitraq.setGroupAColor(groupAColorJPanel.getBackground());
        mitraq.setGroupBColor(groupBColorJPanel.getBackground());

        mitraq.loadItraqData(groupOneLabelJTextField.getText(), groupTwoLabelJTextField.getText(),
                iTraqTypeJComboBox.getSelectedItem().toString(), iTraqReferenceJComboBox.getSelectedItem().toString(),
                new Integer(numberOfExperimentsJSpinner.getValue().toString()), experimentalDesignJTable, ratioFileJTextField.getText(), true);

        this.dispose();


        // a try at adding a progress bar when loading the spectra, works, but throws a java null pointer exception...

//        this.setVisible(false);
//
//        progressDialog = new ProgressDialog(this, this, true);
//
//        new Thread(new Runnable() {
//
//            public void run() {
//                progressDialog.setIntermidiate(true);
//                progressDialog.setTitle("Loading Data. Please Wait...");
//                progressDialog.setVisible(true);
//            }
//        }, "ProgressDialog").start();
//
//        cancelProgress = false;
//
//        final ExperimentalDesign temp = this;
//
//        new Thread("OpenThread") {
//
//            @Override
//            public void run() {
//
//                // store the group colors
//                mitraq.setGroupAColor(groupAColorJPanel.getBackground());
//                mitraq.setGroupBColor(groupBColorJPanel.getBackground());
//
//                mitraq.loadItraqData(groupOneLabelJTextField.getText(), groupTwoLabelJTextField.getText(),
//                        iTraqTypeJComboBox.getSelectedItem().toString(), iTraqReferenceJComboBox.getSelectedItem().toString(),
//                        new Integer(numberOfExperimentsJSpinner.getValue().toString()), experimentalDesignJTable, ratioFileJTextField.getText(), true);
//                progressDialog.setVisible(false);
//                progressDialog.dispose();
//                temp.dispose();
//            }
//        }.start();

    }//GEN-LAST:event_loadJButtonActionPerformed

    /**
     * Updates the list of group lables to choose from.
     *
     * @param evt
     */
    private void numberOfGroupsJSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_numberOfGroupsJSpinnerStateChanged

        int numberOfGroups = new Integer(numberOfGroupsJSpinner.getValue().toString());

        String[] groups = new String[]{groupOneLabelJTextField.getText(), null};

        switch (numberOfGroups) {
            case 1:
                groupTwoLabelJTextField.setEnabled(false);
                break;
            case 2:
                groupTwoLabelJTextField.setEnabled(true);

                groups = new String[]{
                            groupOneLabelJTextField.getText(),
                            groupTwoLabelJTextField.getText(),
                            null};
                break;
        }

        DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer();
        cellRenderer.setHorizontalAlignment(SwingConstants.CENTER);

        experimentalDesignJTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);

        JComboBox comboBox = new JComboBox(groups);
        comboBox.setRenderer(new AlignedListCellRenderer(SwingConstants.CENTER));

        for (int i = 1; i < experimentalDesignJTable.getColumnCount(); i++) {
            if (experimentalDesignJTable.getValueAt(0, i) != null
                    && ((String) experimentalDesignJTable.getValueAt(0, i)).equalsIgnoreCase("Ref")) {
                experimentalDesignJTable.getColumnModel().getColumn(i).setCellRenderer(cellRenderer);
            } else {
                TableColumn col = experimentalDesignJTable.getColumnModel().getColumn(i);
                col.setCellEditor(new MyComboBoxEditor(comboBox));
                col.setCellRenderer(cellRenderer);
            }
        }
}//GEN-LAST:event_numberOfGroupsJSpinnerStateChanged

    /**
     * Opens a color chooser for the color for group 1.
     *
     * @param evt
     */
    private void groupAColorJPanelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_groupAColorJPanelMouseClicked
        Color color = JColorChooser.showDialog(this,
                "Choose a Color", groupAColorJPanel.getBackground());

        if (color != null) {
            groupAColorJPanel.setBackground(color);
            groupAColorJPanel.repaint();
            mitraq.setGroupAColor(color);
        }
    }//GEN-LAST:event_groupAColorJPanelMouseClicked

    /**
     * Opens a color chooser for the color for group 2.
     *
     * @param evt
     */
    private void groupBColorJPanelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_groupBColorJPanelMouseClicked
        Color color = JColorChooser.showDialog(this,
                "Choose a Color", groupBColorJPanel.getBackground());

        if (color != null) {
            groupBColorJPanel.setBackground(color);
            groupBColorJPanel.repaint();
            mitraq.setGroupBColor(color);
        }
    }//GEN-LAST:event_groupBColorJPanelMouseClicked
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel backgroundPanel;
    private javax.swing.JScrollPane expDesignJScrollPane;
    private javax.swing.JTable experimentalDesignJTable;
    private javax.swing.JPanel experimentalSetupPanel;
    private javax.swing.JButton findInputFileJButton;
    private javax.swing.JPanel groupAColorJPanel;
    private javax.swing.JPanel groupBColorJPanel;
    private javax.swing.JTextField groupOneLabelJTextField;
    private javax.swing.JTextField groupTwoLabelJTextField;
    private javax.swing.JComboBox iTraqReferenceJComboBox;
    private javax.swing.JComboBox iTraqTypeJComboBox;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JButton loadJButton;
    private javax.swing.JSpinner numberOfExperimentsJSpinner;
    private javax.swing.JSpinner numberOfGroupsJSpinner;
    private javax.swing.JTextField ratioFileJTextField;
    private javax.swing.JPanel ratioFilePanel;
    // End of variables declaration//GEN-END:variables

    /**
     * Tries to read the file containing the experimental design settings for a
     * previously used iTRAQ data file.
     *
     * @param settingsFile the settings file
     */
    private void readExperimentalDesignSettings(String file) {

        File settingsFile = new File(file);

        try {
            FileReader f = new FileReader(settingsFile);
            BufferedReader b = new BufferedReader(f);

            numberOfExperimentsJSpinner.setValue(new Integer(b.readLine().substring("Number of Experiments: ".length())));
            numberOfGroupsJSpinner.setValue(new Integer(b.readLine().substring("Number of Groups: ".length())));

            groupOneLabelJTextField.setText(b.readLine().substring("Group 1: ".length()));
            groupAColorJPanel.setBackground(new Color(new Integer(b.readLine().substring("Group 1 Color: ".length()))));
            groupTwoLabelJTextField.setText(b.readLine().substring("Group 2: ".length()));
            groupBColorJPanel.setBackground(new Color(new Integer(b.readLine().substring("Group 2 Color: ".length()))));

            iTraqTypeJComboBox.setSelectedItem(b.readLine().substring("iTRAQType: ".length()));
            iTraqReferenceJComboBox.setSelectedItem(b.readLine().substring("iTRAQReference: ".length()));

            b.readLine(); // reads the ExperimentalDesign: line

            String currentLine = b.readLine();

            int rowCounter = 0;

            while (currentLine != null) {

                StringTokenizer tok = new StringTokenizer(currentLine, "\t");

                int columnCounter = 1;

                while (tok.hasMoreTokens()) {

                    String tempToken = tok.nextToken();

                    if (tempToken.equalsIgnoreCase("null")) {
                        tempToken = null;
                    }

                    experimentalDesignJTable.setValueAt(tempToken, rowCounter, columnCounter++);
                }

                currentLine = b.readLine();
                rowCounter++;
            }

            b.close();
            f.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Update the experimental design table according to the currently selected
     * values.
     */
    private void updateExperiementalDesign() {

        int numberOfRows = new Integer(numberOfExperimentsJSpinner.getValue().toString());

        int numberOfColumns = 5; // defaults to 4-plex

        String currentITraqType = iTraqTypeJComboBox.getSelectedItem().toString();

        if (currentITraqType.equalsIgnoreCase("8-plex")) {
            numberOfColumns = 9;
        }

        Object[][] data = new Object[numberOfRows][numberOfColumns];

        for (int i = 0; i < data.length; i++) {
            data[i][0] = new Integer(i + 1);
        }

        Object[] columnNames = new Object[numberOfColumns];

        columnNames[0] = "Exp.";

        Vector<String> iTraqLabels = iTraq4PlexLabels;

        if (currentITraqType.equalsIgnoreCase("8-plex")) {
            iTraqLabels = iTraq8PlexLabels;
        }

        int currentColumnIndex = 1;

        for (int i = 0; i < iTraqLabels.size(); i++) {
            String currentLabel = iTraqLabels.get(i);
            columnNames[currentColumnIndex++] = currentLabel;
        }

        experimentalDesignJTable.setModel(new javax.swing.table.DefaultTableModel(
                data,
                columnNames) {

            public Class getColumnClass(int columnIndex) {
                if (columnIndex == 0) {
                    return java.lang.Integer.class;
                } else {
                    return java.lang.String.class;
                }
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                if (columnIndex == 0) {
                    return false;
                } else {
                    if (experimentalDesignJTable.getValueAt(0, columnIndex) != null
                            && ((String) experimentalDesignJTable.getValueAt(0, columnIndex)).equalsIgnoreCase("Ref")) {
                        return false;
                    }

                    return true;
                }
            }
        });

        experimentalDesignJTable.getColumn("Exp.").setMaxWidth(40);

        String currentReference = iTraqReferenceJComboBox.getSelectedItem().toString();
        int columnIndexOfReference = experimentalDesignJTable.getColumn(currentReference).getModelIndex();

        for (int i = 0; i < experimentalDesignJTable.getRowCount(); i++) {
            ((DefaultTableModel) experimentalDesignJTable.getModel()).setValueAt("Ref", i, columnIndexOfReference);
        }

        numberOfGroupsJSpinnerStateChanged(null);
    }

    @Override
    public void cancelProgress() {
        cancelProgress = true;
    }

    /**
     * A simple combobox editor used in the results table.
     */
    public class MyComboBoxEditor extends DefaultCellEditor {

        /**
         * The constructor for the combo box editor.
         *
         * @param comboBox
         */
        public MyComboBoxEditor(JComboBox comboBox) {
            super(comboBox);
        }
    }
}
